package com.adan.content.service.jobhandler;


import com.adan.base.execption.XcPlusException;
import com.adan.content.feignclient.SearchServiceClient;
import com.adan.content.model.dto.CourseIndex;
import com.adan.content.model.po.CoursePublish;
import com.adan.content.service.CoursePublishService;
import com.adan.message.model.po.MqMessage;
import com.adan.message.service.MessageProcessAbstract;
import com.adan.message.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * @author Mr.M
 * @version 1.0
 * @description 课程发布的任务类
 * @date 2023/2/21 16:15
 */
@Slf4j
@Component
public class CoursePublishTask extends MessageProcessAbstract {

    @Autowired
    private CoursePublishService coursePublishService;

    @Autowired
    private SearchServiceClient searchServiceClient;

    // 任务调度入口
    @XxlJob("CoursePublishJobHandler")
    public void coursePublishJobHandler() throws Exception {

        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();// 执行器的序号，从0开始
        int shardTotal = XxlJobHelper.getShardTotal();// 执行器总数
        // 调用抽象类的方法执行任务
        process(shardIndex, shardTotal, "course_publish", 30, 60);
    }

    // 执行课程发布任务的逻辑,如果此方法抛出异常说明任务执行失败
    @Override
    public boolean execute(MqMessage mqMessage) {
        // 从mqMessage拿到课程id
        Long courseId = Long.parseLong(mqMessage.getBusinessKey1());

        // 课程静态化并上传到minio
        generateCourseHtml(mqMessage, courseId);

        // 课程es索引
        saveCourseIndex(mqMessage, courseId);
        // 课程redis缓存
        saveCourseCache(mqMessage, courseId);


        // 返回true表示任务完成
        return true;
    }


    // 生成课程静态化页面并上传至文件系统 第一个阶段任务
    private void generateCourseHtml(MqMessage mqMessage, long courseId) {
        // 消息id
        Long taskId = mqMessage.getId();
        MqMessageService mqMessageService = this.getMqMessageService();
        // 1. 做任务幂等性处理
        // 查询数据库取出该阶段执行状态
        int stageOne = mqMessageService.getStageOne(taskId);
        if (stageOne > 0) {
            log.debug("课程静态化任务完成，无需处理...");
            return;
        }
        // 2. 开始进行课程静态化
        File file = coursePublishService.generateCourseHtml(courseId);
        if (file == null) {
            XcPlusException.cast("课程静态化异常");
        }
        // 3. 将静态页面上传至MinIO
        coursePublishService.uploadCourseHtml(courseId, file);

        // 4. 保存第一阶段状态
        mqMessageService.completedStageOne(taskId);


    }

    // 保存课程索引信息 第二个阶段任务
    private void saveCourseIndex(MqMessage mqMessage, long courseId) {
        // 任务id
        Long taskId = mqMessage.getId();
        // 消息处理的service
        MqMessageService mqMessageService = this.getMqMessageService();
        // 取出第二个阶段状态
        int stageTwo = mqMessageService.getStageTwo(taskId);
        // 任务幂等性处理
        if (stageTwo > 0) {
            log.debug("课程索引信息已写入，无需执行...");
            return;
        }

        //取出课程发布信息
        CoursePublish coursePublish = coursePublishService.getById(courseId);
        CourseIndex courseIndex = new CourseIndex();
        //拷贝至课程索引对象
        BeanUtils.copyProperties(coursePublish, courseIndex);
        //远程调用搜索服务api添加课程信息到索引
        Boolean add = searchServiceClient.add(courseIndex);
        if (!add){
            XcPlusException.cast("添加索引失败");
        }
        // 完成本阶段的任务
        mqMessageService.completedStageTwo(taskId);


    }

    // TODO:将课程信息缓存至redis 第三个阶段任务
    private void saveCourseCache(MqMessage mqMessage, Long courseId) {
        log.debug("将课程信息缓存至redis,课程id:{}", courseId);


    }
}
